<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>js做的画板-jq22.com</title>
<script src="https://libs.baidu.com/jquery/1.11.3/jquery.min.js"></script>
<style>
canvas {
	background:#ccc;
	display:block;
	margin:0 auto;
}
#controls {
	width:200px;
	height:100%;
	position:absolute;
	left:0;
	top:0;
	background:linear-gradient(to bottom,#000000,#b8b8b8);
	user-select:none;
}
#controls section {
	margin-top:10px;
	height:20px;
}
#controls .label {
	width:50%;
	height:20px;
	line-height:20px;
	text-align:center;
	color:#FFF;
	display:block;
	float:left;
}
#xing {
	float:right;
	width:50%;
	height:20px;
}
/*#shape {
	*/
        /*width:50%;
	height:20px;
	display:block;
	*/
        /*
}
*/
        #controls .color {
	width:50%;
	height:auto;
	float:right;
}
#colors input {
	float:right;
	width:48%;
	height:20px;
	border:none;
}
#widths input {
	float:right;
	width:49%;
	height:20px;
	border:none;
}
#style {
	float:right;
	width:49%;
	height:20px;
	border:none;
}
input[type=button] {
	width:150px;
	height:30px;
	background:#C40000;
	color:#FFF;
	border-radius:5px;
	margin-top:10px;
	margin-left:10px;
	border:none;
	display:block;
}
</style>
</head>
<body>
<canvas width="500" height="500"></canvas>
<div id="controls">
 
    <section id="shape">
        <label for="shape" class="label">选择形状 : </label>
        <select id="xing">
            <option value="rect">矩形</option>
            <option value="line">直线</option>
            <option value="circle">内切圆</option>
            <option value="circle1">外接圆</option>
            <option value="circle2">中心圆</option>
            <option value="poly">多边形</option>
            <option value="pen">铅笔</option>
            <option value="eraser">橡皮</option>
        </select>
    </section>
 
    <section id="colors">
        <label for="color" class="label">选择颜色 : </label>
        <input type="color" id="color">
    </section>
    <section id="widths">
        <label for="color" class="label">选择线宽 : </label>
        <input type="number" id="width" value="2" step="2" min="2" max="20">
    </section>
    <section id="styles">
        <label for="shape" class="label">选择方式 : </label>
        <select id="style">
            <option value="stroke">描边</option>
            <option value="fill">填充</option>
        </select>
    </section>
    <section id="sides">
        <label for="side" class="label">选择边数 : </label>
        <input type="number" id="side" value="3" min="3" max="20">
    </section>
    <input type="button" value="撤销" id="redo">
    <input type="button" value="保存" id="save">
    <input type="button" value="清空" id="qingkong">
</div>
 
<script>
 var canvas = document.querySelector("canvas");
 var cobj = canvas.getContext("2d");
 var shape = document.querySelector("#xing");
 var color = document.querySelector("#color");
 var width = document.querySelector("#width");
 var style = document.querySelector("#style");
 var side = document.querySelector("#side");
 var redo = document.querySelector("#redo");
 var save = document.querySelector("#save");
 var qingkong = document.querySelector("#qingkong");
 console.log(side);
 var data = [];
 var s = "rect";
 shape.onchange = function() {
     s = this.value;
 };
 var c = "#000";
 color.onchange = function() {
     c = this.value;
 };
 var w = "2";
 width.onchange = function() {
     w = this.value;
 };
 var st = "stroke";
 style.onchange = function() {
     st = this.value;
 };
 var sd = "3";
 side.onchange = function() {
     sd = this.value;
 };
 
 canvas.onmousedown = function(e) {
     var ox = e.offsetX;
     var oy = e.offsetY;
     var draw = new Draw(cobj, {
         color: c,
         width: w,
         style: st,
         side: sd
     });
     if (s == "pen") {
         cobj.beginPath();
         cobj.moveTo(ox, oy);
     }
     canvas.onmousemove = function(e) {
         var mx = e.offsetX;
         var my = e.offsetY;
         if (s != "eraser") {
             cobj.clearRect(0, 0, 500, 500);
             if (data.length != 0) {
                 cobj.putImageData(data[data.length - 1], 0, 0, 0, 0, 500, 500); //将某个图像数据放置到画布指定的位置上  后面四个参数可省略
             }
         }
         //            cobj.strokeRect(ox,oy,mx-ox,my-oy);
         // cobj.beginPath()
         draw[s](ox, oy, mx, my, sd);
     };
     document.onmouseup = function() {
         data.push(cobj.getImageData(0, 0, 500, 500)); //获取画布当中指定区域当中所有的图形数据
         canvas.onmousemove = null;
         document.onmouseup = null;
     }
 };
 redo.onclick = function() {
     if (data.length == 0) {
         alert("无效操作");
         return;
     }
     cobj.clearRect(0, 0, 500, 500);
     data.pop();
     if (data.length == 0) {
         return;
     }
     cobj.putImageData(data[data.length - 1], 0, 0, 0, 0, 500, 500);
 };
 save.onclick = function() {
     var r = canvas.toDataURL();
     location.assign(r)
 };
 qingkong.onclick = function() {
     cobj.clearRect(0, 0, 500, 500);
     data = [];
 }
 class Draw {
     constructor(cobj, option) {
         this.cobj = cobj;
         this.color = option.color;
         this.width = option.width;
         this.style = option.style;
     }
     init() { //初始化
         this.cobj.strokeStyle = this.color;
         this.cobj.fillStyle = this.color;
         this.cobj.lineWidth = this.width;
     }
     rect(ox, oy, mx, my) {
         this.init();
         this.cobj.beginPath();
         this.cobj.rect(ox, oy, mx - ox, my - oy);
         this.cobj[this.style]();
 
     }
     line(ox, oy, mx, my) {
         this.init();
         this.cobj.beginPath();
         this.cobj.moveTo(ox, oy);
         this.cobj.lineTo(mx, my);
         this.cobj.stroke();
     }
     circle(ox, oy, mx, my) { //内切圆
         this.init();
         this.cobj.beginPath();
         /*        var r=Math.sqrt(Math.pow(mx-ox,2)+Math.pow(my-oy,2))/2;
                 this.cobj.arc(ox+(mx-ox)/2,oy+(my-oy)/2,r,0,2*Math.PI);*/
         var r = Math.abs(mx - ox) > Math.abs(my - oy) ? Math.abs(my - oy) / 2 : Math.abs(mx - ox) / 2;
         this.cobj.arc(ox + (ox < mx ? r : -r), oy + (oy < my ? r : -r), r, 0, 2 * Math.PI);
         this.cobj[this.style]();
     }
     circle1(ox, oy, mx, my) { //外接圆
         this.init();
         this.cobj.beginPath();
         var r = Math.sqrt(Math.pow(mx - ox, 2) + Math.pow(my - oy, 2)) / 2;
         this.cobj.arc(ox + (mx - ox) / 2, oy + (my - oy) / 2, r, 0, 2 * Math.PI);
         this.cobj[this.style]();
     }
     circle2(ox, oy, mx, my) { //中心圆
         this.init();
         this.cobj.beginPath();
         var r = Math.sqrt(Math.pow(mx - ox, 2) + Math.pow(my - oy, 2));
         this.cobj.arc(ox, oy, r, 0, 2 * Math.PI);
         this.cobj[this.style]();
     }
     poly(ox, oy, mx, my, sd) {
         this.init();
         this.cobj.save();
         cobj.translate(ox, oy);
         this.cobj.rotate(Math.PI / 2);
         var angle = Math.PI / sd;
         var r = Math.sqrt(Math.pow(mx - ox, 2) + Math.pow(my - oy, 2));
         var x = Math.cos(angle) * r;
         var y = Math.sin(angle) * r;
         this.cobj.beginPath();
         this.cobj.moveTo(x, y);
         for (var i = 0; i < sd; i++) {
             this.cobj.lineTo(x, -y);
             this.cobj.rotate(-angle * 2)
         }
         this.cobj[this.style]();
         this.cobj.restore()
     }
     pen(ox, oy, mx, my) {
         this.init();
         this.cobj.lineTo(mx, my);
         this.cobj.stroke();
     }
     eraser(ox, oy, mx, my) {
 
         this.cobj.clearRect(mx, my, 10, 10);
     }
 
 }
</script>
 
</body>
</html>